package com.eportal.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import com.alibaba.fastjson.JSONArray;
import com.eportal.util.*;
import com.opensymphony.xwork2.ActionContext;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Service;

import com.eportal.aop.LogAnnotation;
import com.eportal.base.BaseDAO;
import com.eportal.domain.Sysmenu;
import com.eportal.domain.Sysopt;
import com.eportal.domain.Sysroles;
import com.eportal.service.SysmenuService;
import com.framework.jqgrid.JqGridPager;

/**
 * @author chencheng
 */
@Service("sysmenuService")
public class SysmenuServiceImpl  implements SysmenuService {
	private Map<String, Object> result = new HashMap<String, Object>();
	private static Logger log = Logger.getLogger(SysmenuServiceImpl.class.getName());
	public HttpSession getSession() {
        if(ActionContext.getContext()==null){               //todo 为空表明是springmvc调用 Created by Saber on 2017/8/22 下午2:16
            return CommonUtil.getHttpRequest().getSession();
        }
        return ServletActionContext.getRequest().getSession();
    }
	@Resource(name="dao")
	private BaseDAO dao;

    @Override
    public Sysmenu add(Sysmenu sysmenu) throws Exception {
    	if (!StringUtils.isBlank(sysmenu.getmPno())) {//级别在父级别基础加一
    		sysmenu.setmLevel(sysmenu.getmLevel()+1);
        } else {//父节点为空，则为一级资源
        	sysmenu.setmPno(0+"");
        	sysmenu.setmLevel(0);
        }
    	sysmenu.setMct(new Timestamp(System.currentTimeMillis()));
    	sysmenu.setmIsLeaf("1");//新增资源都为叶子点
    	sysmenu.setStatus("1");
    	dao.save(sysmenu);
        // 将上级mIsLeaf设置为false
        if (!"0".equals(sysmenu.getmPno())) {
        	Sysmenu s = get(Long.parseLong(sysmenu.getmPno()));
            s.setmIsLeaf("0");
            dao.update(s);
        }
        return sysmenu;
    }

    @Override
    public void delete(Long id) {
        Sysmenu resource = (Sysmenu) dao.getById(Sysmenu.class, id);
        dao.delete(resource);
    }

    @Override
    public void update(Sysmenu resource) throws Exception {
    	dao.update(resource);
    }

    @Override
    public List<Map<String, Object>> list(JqGridPager page) {
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        List<Sysmenu> sysmenus = dao.query(" from Sysmenu order by mType,cast(mPno as int),cast(msort as int)");
        sysmenus = sort(sysmenus);
        for (Sysmenu sysmenu : sysmenus) {
            Map<String, Object> obj = new HashMap<String, Object>();
            obj.put("mName", sysmenu.getmName());
            obj.put("mcname", sysmenu.getMcname());
            obj.put("sid", sysmenu.getSid());
            obj.put("mUrl", sysmenu.getmUrl());
            obj.put("mType", sysmenu.getmType());
            obj.put("isLeaf", "1".equals(sysmenu.getmIsLeaf()));
            obj.put("parent", sysmenu.getmPno());
            obj.put("level", sysmenu.getmLevel());
            obj.put("mSort", sysmenu.getmSort());
            obj.put("expanded", false);
            obj.put("loaded", true);
            result.add(obj);
        }
        return result;
    }


    @Override
    public Sysmenu get(Long id) {
        return (Sysmenu) dao.getById(Sysmenu.class, id);
    }


    /**
     * 获取用户对应的菜单
     *
     * @param user
     * @return
     */
//    public List<Sysmenu> loadMenu(Sysopt sysopt) {
//        // 获取用户对应的角色
//        String[] roleIds = sysopt.getRoles().split("|");
//        final List<Long> tmp = new LinkedList<Long>();
//        for (String s : roleIds) {
//            tmp.add(Long.parseLong(s));
//        }
//        List list = getHibernateTemplate().executeFind(new HibernateCallback() {
//            @Override
//            public Object doInHibernate(Session session) throws HibernateException, SQLException {
//                Query query = session.createQuery("select mList from Sysroles where sid in (:roleIds) and status='1'")
//                        .setParameterList("roleIds", tmp);
//                return query.list();
//
//            }
//        });
//
//        final List<Long> rids = new LinkedList<Long>();
//        StringBuffer sb = new StringBuffer();
//        for (Object r : list) {
//            sb.append(r);
//            sb.append(",");
//        }
//        String[] temp = sb.toString().split(",");
//        for (String s : temp) {
//            rids.add(Long.parseLong(s));
//        }
//        List<Sysmenu> resources = getHibernateTemplate().executeFind(new HibernateCallback() {
//            @Override
//            public Object doInHibernate(Session session) throws HibernateException, SQLException {
//                Query query = session.createQuery("from Sysmenu where rType = 0 and id in (:rids) order by mPno,mSort")
//                        .setParameterList("rids", rids);
//                return query.list();
//            }
//        });
//        resources = sort(resources);
//        return resources;
//    }

    @Override
    public Map<String, Object> loadAuths(Sysopt sysopt,int userRole) {

        Map<String, Object> result = new HashMap<String, Object>();
        StringBuffer sb = new StringBuffer();
        List<Sysmenu> sysmenus = null;
        if("-1".equals(sysopt.getIsAdmin())){
        	sysmenus = dao.query(" from Sysmenu where type=0 and status='1' order by cast(mPno as int),cast(msort as int)");
        }else{
	        // 获取用户对应的角色
	        String[] roleIds = sysopt.getRoles().split("\\|");
	        final List<Long> tmp = new LinkedList<Long>();
	        for (String s : roleIds) {
	            tmp.add(Long.parseLong(s));
	        }
	        if ("-1".equals(roleIds[0])) {
	        	 result.put("auths",null);
	        	 return result;
			}
	        //获取角色中的菜单id集合
	        String sql = "select mList from Sysroles where sid in (:roleIds) and status='1'";
	        List<String> list = dao.executeFind(sql,"roleIds",tmp);
	        if(list == null || list.size()<1){
	        	return result;
	        }
	        //菜单id去重
	        List<String> listRids = new LinkedList<String>();
	    	for(String s : list){
	    		String[] arr = s.split("\\|");
	    		List<String> listArr = Arrays.asList(arr);
	    		listRids.removeAll(listArr);
	    		listRids.addAll(listArr);
	    	}

	    	final List<Long> rids = new LinkedList<Long>();
	    	for (String str : listRids) {
				rids.add(Long.parseLong(str));
			}

	    	//获取对应菜单
	    	String sqlMenu = "from Sysmenu where sid in (:rids) and type=0 order by cast(mPno as int),cast(msort as int)";
	    	sysmenus = dao.executeFind(sqlMenu,"rids",rids);

        }
        if(sysmenus == null || sysmenus.size()<1){
        	return result;
        }
        //展示菜单集合
        List<Sysmenu> menus = new ArrayList<Sysmenu>();
        //除按钮以外的所有菜单，用于页面判断连接的权限
        List<Sysmenu> menusAll = new ArrayList<Sysmenu>();
        //button集合
        Map<String, Object> buttons_temp = new HashMap<String, Object>();

//        int userRole =  (Integer) getSession().getAttribute("userRole");  //todo Updated by Saber on 2017/8/8 下午2:34
//        Sysopt user = (Sysopt) getSession().getAttribute("user");     //todo Updated by Saber on 2017/8/8 下午2:34
        Map<String, Object> map = new HashMap<String, Object>();
        for (Sysmenu sysmenu : sysmenus) {
        	//菜单集合
            if (!"4".equals(sysmenu.getmType()) ) {
                if (!menus.contains(sysmenu)) {
                	if(userRole == 1 || userRole == 2 || userRole == 21){
						String str = Config.SYSTEMHIDE;
						if (str.indexOf(","+sysmenu.getMcname()+",") < 0) {
							menus.add(sysmenu);
						}
					}
                	if(userRole == 3 || userRole == 4 || userRole==7 ){ //todo Updated by Saber on 2017/7/25 下午5:01
                		String str = Config.TAGENTHIDE;
						if (str.indexOf(","+sysmenu.getMcname()+",") < 0) {
							menus.add(sysmenu);
						}
					}
                	if(userRole == 5 || userRole == 6){
                		String str = Config.TCOMMUNITYHIDE;
						if (str.indexOf(","+sysmenu.getMcname()+",") < 0) {
							menus.add(sysmenu);
						}
					}
                	menusAll.add(sysmenu);
                }
                String url = sysmenu.getmUrl();
                if (url != null && url.trim().length() > 0) {
                    map.put(sysmenu.getSid() + "", url);
                }
            }
            //按钮集合
            if ("4".equals(sysmenu.getmType())) {
                List<Sysmenu> sl = null;
                if (buttons_temp.containsKey(sysmenu.getmPno())) {
                    sl = (List<Sysmenu>) buttons_temp.get(sysmenu.getmPno());
                    sl.add(sysmenu);
                } else {
                    sl = new ArrayList<Sysmenu>();
                    sl.add(sysmenu);
                }
                buttons_temp.put(sysmenu.getmPno(), sl);//值为父节点（菜单）的sid，值为按钮的sysmenu对象
            }
            String url = sysmenu.getmUrl();
            if (url != null && url.trim().length() > 0) {
                if (sb.indexOf(url) < 0) {
                    sb.append(url + ",");
                }
            }
        }

        Map<String, Object> buttons = new HashMap<String, Object>();
        Set<Map.Entry<String, Object>> set = buttons_temp.entrySet();
        for (Iterator iter = set.iterator(); iter.hasNext(); ) {
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iter.next();
            String key = entry.getKey();
            String url = (String) map.get(key);
            buttons.put(url, entry.getValue());//key为父节点的URL,值为buttons的sysmenu对象
        }

        buttons_temp = null;
        result.put("auths", sb.toString());
        result.put("buttons", buttons);
        result.put("menus", menus);//加载菜单
        result.put("menusAll", menusAll);//除按钮以外的所有菜单，用于页面判断连接的权限
        //TODO wangk 2017-7-26 17:14:55 改成string类型其他地方出错
//        result.put("sysmenus", JSONArray.toJSONString(sysmenus));//用于权限菜单的分配 //todo Created by Saber on 2017/7/18 下午10:15
        result.put("sysmenus", sysmenus);//用于权限菜单的分配 //todo Created by Saber on 2017/7/18 下午10:15
        return result;
    }


  //map转对象
    public List<Sysmenu> getSysmenu(List<Map<String, Object>> listSysmenuMap) {
    	Sysmenu sysmenu = null;
    	List<Sysmenu> sysmenus = new ArrayList<Sysmenu>();
    	for (Map<String, Object> map : listSysmenuMap) {
    		sysmenu = new Sysmenu();
    		sysmenu.setSid(Long.parseLong(map.get("sid").toString()));
    		sysmenu.setmName(map.get("mName").toString());
    		String url = map.get("mUrl").toString();
			if (url != null && url.trim().length() > 0) {
				String[] temp = url.split(",");
				sysmenu.setmUrl(temp[0]);
			}
    		sysmenu.setmPno(map.get("mPno").toString());
    		sysmenu.setmLevel(Integer.parseInt(map.get("mLevel").toString()));
    		sysmenu.setmSort(map.get("mSort").toString());
    		sysmenu.setmIsLeaf(map.get("mIsLeaf").toString());
    		sysmenu.setStatus(map.get("status").toString());
    		sysmenu.setmType(map.get("mType").toString());
    		sysmenu.setType(Integer.parseInt(map.get("ttype").toString()));
    		sysmenu.setMcname(map.get("mcname").toString());
    		if (map.get("picName")!=null) {
    			sysmenu.setPicName(map.get("picName").toString());
			}
    		sysmenus.add(sysmenu);
		}
		return sysmenus;
	}

    // list to tree
    public LinkedList<Sysmenu> sort(List<Sysmenu> resources) {
        LinkedList<Sysmenu> result = new LinkedList<Sysmenu>();
        for (Iterator<Sysmenu> iter = resources.iterator(); iter.hasNext(); ) {
            Sysmenu r = iter.next();
            iter.remove();
            if (!result.contains(r)) {
                result.add(r);
                tree(resources, r, result);
            }
        }
        return result;
    }

    public void tree(List<Sysmenu> resources, Sysmenu e, LinkedList<Sysmenu> result) {
        for (Iterator<Sysmenu> iter = resources.iterator(); iter.hasNext(); ) {
            Sysmenu r = iter.next();
            Long mPno = Long.parseLong(r.getmPno());
            if (mPno.intValue() == e.getSid().intValue()) {
                result.add(r);
                tree(resources, r, result);
            }
        }
    }

	@Override
	public List<Sysmenu> listMenu(Sysroles role) {
		 final List<Long> rids = new LinkedList<Long>();
		 String[] roleIds = role.getmList().split("\\|");
         for (String s : roleIds) {
        	 rids.add(Long.parseLong(s));
         }
         String sql = "from Sysmenu where id in (:rids) and type=0 order by cast(mPno as int),cast(msort as int)";
         List<Sysmenu> resources = dao.executeFind(sql,"rids",rids);
	        resources = sort(resources);
	        return resources;
	}

	 /**
     * 资源新增保存
     * @author chencheng
     */
	@Override
    @LogAnnotation(operateDescribe="资源菜单新增")
    public Map<String, Object> addMethod(Sysmenu sysmenu){
        String msg = ValidateUtil.validate(sysmenu);
        if (msg == null || msg.trim().length() == 0) {
            try {
            	sysmenu = add(sysmenu);
                result.put("code", 1);
                result.put("msg", "操作成功");
                result.put("objectId", sysmenu.getSid());
            } catch (Exception e) {
                log.error("权限保存失败", e);
                result.put("code", 0);
                result.put("msg", "操作失败");
            }
        } else {
            result.put("code", 0);
            result.put("msg", msg);
        }
		return result;
    }

	/**
     * 资源修改保存
     * @author chencheng
     */
	@Override
    @LogAnnotation(operateDescribe="资源菜单修改")
    public Map<String, Object>  updateMethod(Sysmenu sysmenu){
        String msg = ValidateUtil.validate(sysmenu);
        result.put("objectId", sysmenu.getSid());
        if (msg == null || msg.trim().length() == 0) {
            try {
            	Sysmenu entity = get(sysmenu.getSid());
            	entity.setmName(sysmenu.getmName());
            	entity.setMcname(sysmenu.getMcname());
            	entity.setmIcon(sysmenu.getmIcon());
            	entity.setType(sysmenu.getType());
            	entity.setmType(sysmenu.getmType());
            	entity.setmUrl(sysmenu.getmUrl());
            	entity.setmSort(sysmenu.getmSort());
            	entity.setMmt(new Timestamp(System.currentTimeMillis()));
                update(entity);
                result.put("code", 1);
                result.put("msg", "操作成功");
            } catch (Exception e) {
                log.error("权限更新失败", e);
                result.put("code", 0);
                result.put("msg", "操作失败");
            }
        } else {
            result.put("code", 0);
            result.put("msg", msg);
        }
		return result;
    }


	/**
     * 资源删除
     * @author chencheng
     */
	@Override
    @LogAnnotation(operateDescribe="资源菜单删除")
    public Map<String, Object> deleteMethod(Long sid){
        try {
        	result.put("objectId", sid);
            delete(sid);
            result.put("code", 1);
            result.put("msg", "操作成功");
        } catch (Exception e) {
            log.error("权限删除失败", e);
            result.put("code", 0);
            result.put("msg", "操作失败");
        }
		return result;
    }

	public List<Map<String, Object>> getButton(String listViewUrl){
	List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
	List<Sysmenu> resources = null;
    Map<String, Object> map = (Map<String, Object>) getSession().getAttribute("auths");
        if(map == null) return null;    //todo 增加非空判断 Created by Saber on 2017/8/22 下午2:21
    map = (Map<String, Object>) map.get("buttons");
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        String key = entry.getKey();
        if (key.contains(listViewUrl)) {
            resources = (List<Sysmenu>) entry.getValue();
        }
    }
    if (resources != null && resources.size() > 0) {
        for (Sysmenu r : resources) {
            Map<String, Object> m = BeanMapUtils.toMap(r);
            result.add(m);
        }
    }
	return result;
	}

	/**
	 * 积分规则查询
	 */
	@Override
	public List<Map<String, String>> scoreList(String where) {
		String sql = "select s.mname,s.murl from sysmenu s where "+where;
		return dao.queryBySql(sql);
	}

	@Override
	public Sysmenu getByMenuUrl(String url) {
		 StringBuffer sb = new StringBuffer("from Sysmenu where mUrl like '%");
 		 sb.append(url);
 		 sb.append("%'");
		return (Sysmenu) dao.loadObject(sb.toString());
	}
}
